import math
import re
from StockPro.ClassStock import Stock


class StockFunc:
    def read(self, code, name):
        data = Stock()
        data.name = name
        fr = open("./data/" + code + ".csv", "r", encoding='gbk')
        next(fr)
        for line in fr:
            line = re.sub("\n", "", line)
            tmp = line.split(',')
            data.days += 1
            data.date.append(tmp[0])
            data.closeprice.append(float(tmp[3]))
            data.highprice.append(float(tmp[4]))
            data.lowprice.append(float(tmp[5]))
        fr.close()
        data.closeprice.reverse()
        data.highprice.reverse()
        data.lowprice.reverse()
        return data

    def MACD(self, close_price, fastpeiord, slowpeiord, signalperiod):
        close = close_price[:]
        # close.insert(0, 0)
        if len(close) == 0:
            return [0], [0], [0]
        EMA1 = []
        EMA2 = []
        EMA1.append(close[0])
        EMA2.append(close[0])
        DIFF = [0]
        DEA = [0]
        BAR = [0]
        for close in close[1:]:
            e1 = 2 * close / (fastpeiord + 1) + EMA1[-1] * (fastpeiord - 1) / (fastpeiord + 1)
            e2 = 2 * close / (slowpeiord + 1) + EMA2[-1] * (slowpeiord - 1) / (slowpeiord + 1)
            diff = e1 - e2
            dea = 2 * diff / (signalperiod + 1) + (signalperiod - 1) * DEA[-1] / (signalperiod + 1)
            bar = 2 * (diff - dea)
            EMA1.append(e1)
            EMA2.append(e2)
            DIFF.append(diff)
            DEA.append(dea)
            BAR.append(bar)
        return DIFF, DEA, BAR

    def CCI(self, high_price, low_price, close_price, n):
        high = high_price[:]
        low = low_price[:]
        close = close_price[:]
        if len(high) < n:
            return [0] * len(high)
        TYP = []
        cci = []
        for i in range(n - 1):
            TYP.append((high[i] + low[i] + close[i]) / 3)
        for i in range(n - 1, len(high)):
            TYP.append((high[i] + low[i] + close[i]) / 3)
            MA = sum(TYP[len(TYP) - n:]) / n
            tmp = 0
            for j in TYP[len(TYP) - n:]:
                tmp += math.fabs(j - MA)
            AVEDEV = tmp / n
            if AVEDEV != 0:
                cci.append((TYP[-1] - MA) * 1000 / (15 * AVEDEV))
            else:
                cci.append(0)
        return cci

    def KDJ(self, high_price, low_price, close_price, n, M1, M2):
        high = high_price[:]
        low = low_price[:]
        close = close_price[:]
        high.insert(0, 0)
        low.insert(0, 0)
        close.insert(0, 0)
        RSV = []
        K = []
        D = []
        J = []
        RSV.append(0.0)
        K.append(50.0)
        D.append(50.0)
        J.append(0.0)
        for i in range(1, len(high)):
            if i - n + 1 < 0:
                llv = min(low[1:i + 1])
                hhv = max(high[1:i + 1])
            else:
                llv = min(low[i - n + 1:i + 1])
                hhv = max(high[i - n + 1:i + 1])
            if llv != hhv:
                RSV.append((close[i] - llv) / (hhv - llv) * 100)
            else:
                RSV.append(0)
            K.append((RSV[-1] + (M1 - 1) * K[-1]) / M1)
            D.append((K[-1] + (M2 - 1) * D[-1]) / M2)
            J.append(3 * K[-1] - 2 * D[-1])
        return K[1:], D[1:], J[1:]
